home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / parseblock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-23  |  10.0 KB  |  434 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #define NO_SANITY_CHECKS
  22. #include <config.h>
  23. #include <assert.h>
  24. #include "video.h"
  25. #include "proto.h"
  26. #include "decoders.h"
  27.  
  28. /* External declarations. */
  29.  
  30. extern int zigzag_direct[];
  31.  
  32. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  33.  
  34. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  35.  
  36.  
  37. /*
  38.  *--------------------------------------------------------------
  39.  *
  40.  * ParseReconBlock --
  41.  *
  42.  *    Parse values for block structure from bitstream.
  43.  *      n is an indication of the position of the block within
  44.  *      the macroblock (i.e. 0-5) and indicates the type of 
  45.  *      block (i.e. luminance or chrominance). Reconstructs
  46.  *      coefficients from values parsed and puts in 
  47.  *      block.dct_recon array in vid stream structure.
  48.  *      sparseFlag is set when the block contains only one
  49.  *      coeffictient and is used by the IDCT.
  50.  *
  51.  * Results:
  52.  *    
  53.  *
  54.  * Side effects:
  55.  *      Bit stream irreversibly parsed.
  56.  *
  57.  *--------------------------------------------------------------
  58.  */
  59.  
  60. #define DCT_recon blockPtr->dct_recon
  61. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  62. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  63. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  64.  
  65. #define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
  66. #define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
  67.  
  68. void
  69. ParseReconBlock(n)
  70.      int n;
  71. {
  72. #ifdef RISC
  73.   unsigned int temp_curBits;
  74.   int temp_bitOffset;
  75.   int temp_bufLength;
  76.   unsigned int *temp_bitBuffer;
  77. #endif
  78.  
  79.   Block *blockPtr = &curVidStream->block;
  80.   int coeffCount;
  81.   
  82.   if (bufLength < 100)
  83.     correct_underflow();
  84.  
  85. #ifdef RISC
  86.   temp_curBits = curBits;
  87.   temp_bitOffset = bitOffset;
  88.   temp_bufLength = bufLength;
  89.   temp_bitBuffer = bitBuffer;
  90. #endif
  91.  
  92.   {
  93.     /*
  94.      * Copy the globals curBits, bitOffset, bufLength, and bitBuffer
  95.      * into local variables with the same names, so the macros use the
  96.      * local variables instead.  This allows register allocation and
  97.      * can provide 1-2 fps speedup.  On machines with not so many registers,
  98.      * don't do this.
  99.      */
  100. #ifdef RISC
  101.     register unsigned int curBits = temp_curBits;
  102.     register int bitOffset = temp_bitOffset;
  103.     register int bufLength = temp_bufLength;
  104.     register unsigned int *bitBuffer = temp_bitBuffer;
  105. #endif
  106.  
  107.     int diff;
  108.     int size, level, i, run, pos, coeff;
  109.     short int *reconptr;
  110.     unsigned char *iqmatrixptr, *niqmatrixptr;
  111.     int qscale;
  112.  
  113.     reconptr = DCT_recon[0];
  114.  
  115.     /* 
  116.      * Hand coded version of memset that's a little faster...
  117.      * Old call:
  118.      *    memset((char *) DCT_recon, 0, 64*sizeof(short int));
  119.      */
  120.     {
  121.       INT32 *p;
  122.       p = (INT32 *) reconptr;
  123.  
  124.       p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 
  125.       p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = p[16] = p[17] = p[18] =
  126.       p[19] = p[20] = p[21] = p[22] = p[23] = p[24] = p[25] = p[26] = p[27] =
  127.       p[28] = p[29] = p[30] = p[31] = 0;
  128.  
  129.     }
  130.  
  131.     if (curVidStream->mblock.mb_intra) {
  132.  
  133.       if (n < 4) {
  134.  
  135.     /*
  136.      * Get the luminance bits.  This code has been hand optimized to
  137.      * get by the normal bit parsing routines.  We get some speedup
  138.      * by grabbing the next 16 bits and parsing things locally.
  139.      * Thus, calls are translated as:
  140.      *
  141.      *    show_bitsX  <-->   next16bits >> (16-X)
  142.      *    get_bitsX   <-->   val = next16bits >> (16-flushed-X);
  143.      *               flushed += X;
  144.      *               next16bits &= bitMask[flushed];
  145.      *    flush_bitsX <-->   flushed += X;
  146.      *               next16bits &= bitMask[flushed];
  147.      *
  148.      * I've streamlined the code a lot, so that we don't have to mask
  149.      * out the low order bits and a few of the extra adds are removed.
  150.      *    bsmith
  151.      */
  152.     unsigned int next16bits, index, flushed;
  153.  
  154.     show_bits16(next16bits);
  155.     index = next16bits >> (16-7);
  156.     size = dct_dc_size_luminance[index].value;
  157.     flushed = dct_dc_size_luminance[index].num_bits;
  158.     next16bits &= bitMask[16+flushed];
  159.  
  160.     if (size != 0) {
  161.       flushed += size;
  162.       diff = next16bits >> (16-flushed);
  163.           if (!(diff & bitTest[32-size])) {
  164.         diff = rBitMask[size] | (diff + 1);
  165.       }
  166.     } else {
  167.       diff = 0;
  168.     }
  169.     flush_bits(flushed);
  170.  
  171.     if (n == 0) {
  172.       coeff = diff << 3;
  173.       if (curVidStream->mblock.mb_address -
  174.           curVidStream->mblock.past_intra_addr > 1) 
  175.         coeff += 1024;
  176.       else coeff += DCT_dc_y_past;
  177.       DCT_dc_y_past = coeff;
  178.     } else {
  179.       coeff = DCT_dc_y_past + (diff << 3);
  180.       DCT_dc_y_past = coeff;
  181.     }
  182.       } else {
  183.     
  184.     /*
  185.      * Get the chrominance bits.  This code has been hand optimized to
  186.      * as described above
  187.      */
  188.     unsigned int next16bits, index, flushed;
  189.  
  190.     show_bits16(next16bits);
  191.     index = next16bits >> (16-8);
  192.     size = dct_dc_size_chrominance[index].value;
  193.     flushed = dct_dc_size_chrominance[index].num_bits;
  194.     next16bits &= bitMask[16+flushed];
  195.     
  196.     if (size != 0) {
  197.       flushed += size;
  198.       diff = next16bits >> (16-flushed);
  199.           if (!(diff & bitTest[32-size])) {
  200.         diff = rBitMask[size] | (diff + 1);
  201.       }
  202.     } else {
  203.       diff = 0;
  204.     }
  205.     flush_bits(flushed);
  206.     
  207.     if (n == 4) {
  208.       coeff = diff << 3;
  209.       if (curVidStream->mblock.mb_address -
  210.           curVidStream->mblock.past_intra_addr > 1) 
  211.         coeff += 1024;
  212.       else coeff += DCT_dc_cr_past;
  213.       DCT_dc_cr_past = coeff;
  214.  
  215.     } else {
  216.       coeff = diff << 3;
  217.       if (curVidStream->mblock.mb_address -
  218.           curVidStream->mblock.past_intra_addr > 1) 
  219.         coeff += 1024;
  220.       else coeff += DCT_dc_cb_past;
  221.       DCT_dc_cb_past = coeff;
  222.     }
  223.       }
  224.       
  225.       *reconptr = coeff;
  226.       i = 0; pos = 0;
  227.       coeffCount = (coeff != 0);
  228.     
  229.       if (curVidStream->picture.code_type != 4) {
  230.     
  231.     qscale = curVidStream->slice.quant_scale;
  232.     iqmatrixptr = curVidStream->intra_quant_matrix[0];
  233.     
  234.     while(1) {
  235.       
  236.       DECODE_DCT_COEFF_NEXT(run, level);
  237.  
  238.       if (run == END_OF_BLOCK) break;
  239.  
  240.       i = i + run + 1;
  241.       pos = zigzag_direct[i];
  242.       coeff = (level * qscale * ((int) iqmatrixptr[pos])) >> 3;
  243.       if (level < 0) {
  244.           coeff += (coeff & 1);
  245.       } else {
  246.           coeff -= (coeff & 1);
  247.       }
  248.  
  249.       reconptr[pos] = coeff;
  250.       if (coeff) {
  251.         coeffCount++;
  252.       }
  253.  
  254.     }
  255.  
  256.     flush_bits(2);
  257.  
  258.     goto end;
  259.       }
  260.     }
  261.     
  262.     else {
  263.       
  264.       niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
  265.       qscale = curVidStream->slice.quant_scale;
  266.       
  267.       DECODE_DCT_COEFF_FIRST(run, level);
  268.       i = run;
  269.  
  270.       pos = zigzag_direct[i];
  271.       if (level < 0) {
  272.       coeff = (((level<<1) - 1) * qscale * 
  273.            ((int) (niqmatrixptr[pos]))) >> 4; 
  274.       coeff += (coeff & 1);
  275.       } else {
  276.       coeff = (((level<<1) + 1) * qscale * 
  277.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  278.       coeff -= (coeff & 1);
  279.       }
  280.       reconptr[pos] = coeff;
  281.       if (coeff) {
  282.     coeffCount = 1;
  283.       }
  284.  
  285.       if (curVidStream->picture.code_type != 4) {
  286.     
  287.     while(1) {
  288.       
  289.       DECODE_DCT_COEFF_NEXT(run, level);
  290.  
  291.       if (run == END_OF_BLOCK) break;
  292.  
  293.       i = i+run+1;
  294.       pos = zigzag_direct[i];
  295.       if (level < 0) {
  296.           coeff = (((level<<1) - 1) * qscale * 
  297.                ((int) (niqmatrixptr[pos]))) >> 4; 
  298.           coeff += (coeff & 1);
  299.       } else {
  300.           coeff = (((level<<1) + 1) * qscale * 
  301.                ((int) (*(niqmatrixptr+pos)))) >> 4; 
  302.           coeff -= (coeff & 1);
  303.       }
  304.       reconptr[pos] = coeff;
  305.       if (coeff) {
  306.         coeffCount++;
  307.       }
  308.     }
  309.  
  310.     flush_bits(2);
  311.  
  312.     goto end;
  313.       }
  314.     }
  315.     
  316.   end:
  317.  
  318.     if (coeffCount == 1) mpeg_j_rev_dct_sparse (reconptr, pos);
  319.     else mpeg_j_rev_dct(reconptr);
  320.  
  321. #ifdef RISC
  322.     temp_curBits = curBits;
  323.     temp_bitOffset = bitOffset;
  324.     temp_bufLength = bufLength;
  325.     temp_bitBuffer = bitBuffer;
  326. #endif
  327.  
  328.   }
  329.  
  330. #ifdef RISC
  331.   curBits = temp_curBits;
  332.   bitOffset = temp_bitOffset;
  333.   bufLength = temp_bufLength;
  334.   bitBuffer = temp_bitBuffer;
  335. #endif
  336. }
  337.     
  338. #undef DCT_recon 
  339. #undef DCT_dc_y_past 
  340. #undef DCT_dc_cr_past 
  341. #undef DCT_dc_cb_past 
  342.  
  343.  
  344. /*
  345.  *--------------------------------------------------------------
  346.  *
  347.  * ParseAwayBlock --
  348.  *
  349.  *    Parses off block values, throwing them away.
  350.  *      Used with grayscale dithering.
  351.  *
  352.  * Results:
  353.  *    None.
  354.  *
  355.  * Side effects:
  356.  *      None.
  357.  *
  358.  *--------------------------------------------------------------
  359.  */
  360.  
  361. void
  362. ParseAwayBlock(n)
  363.      int n;
  364. {
  365.   unsigned int diff;
  366.   unsigned int size, run;
  367.   int level;
  368.  
  369.   if (bufLength < 100)
  370.     correct_underflow();
  371.  
  372.   if (curVidStream->mblock.mb_intra) {
  373.  
  374.     /* If the block is a luminance block... */
  375.  
  376.     if (n < 4) {
  377.  
  378.       /* Parse and decode size of first coefficient. */
  379.  
  380.       DecodeDCTDCSizeLum(size);
  381.  
  382.       /* Parse first coefficient. */
  383.  
  384.       if (size != 0) {
  385.     get_bitsn(size, diff);
  386.       }
  387.     }
  388.  
  389.     /* Otherwise, block is chrominance block... */
  390.  
  391.     else {
  392.  
  393.       /* Parse and decode size of first coefficient. */
  394.  
  395.       DecodeDCTDCSizeChrom(size);
  396.  
  397.       /* Parse first coefficient. */
  398.  
  399.       if (size != 0) {
  400.     get_bitsn(size, diff);
  401.       }
  402.     }
  403.   }
  404.  
  405.   /* Otherwise, block is not intracoded... */
  406.  
  407.   else {
  408.  
  409.     /* Decode and set first coefficient. */
  410.  
  411.     DECODE_DCT_COEFF_FIRST(run, level);
  412.   }
  413.  
  414.   /* If picture is not D type (i.e. I, P, or B)... */
  415.  
  416.   if (curVidStream->picture.code_type != 4) {
  417.  
  418.     /* While end of macroblock has not been reached... */
  419.  
  420.     while (1) {
  421.  
  422.       /* Get the dct_coeff_next */
  423.  
  424.       DECODE_DCT_COEFF_NEXT(run, level);
  425.  
  426.       if (run == END_OF_BLOCK) break;
  427.     }
  428.  
  429.     /* End_of_block */
  430.  
  431.     flush_bits(2);
  432.   }
  433. }
  434.